#ifndef __MARS_GOBJECT_CAMERA_H__
#define __MARS_GOBJECT_CAMERA_H__

#include "MarsGameObject.h"
#include "MarsType.h"

namespace GObject
{

class Camera : public GameObject
{
public:
	enum							ProjectType
	{
		PT_PERSPECTIVE				= 0,
		PT_ORTHOGRAPHIC				= 1,
	};

	//////////////////////////////////////////////////////////////////////////
	static void*					operator new ( Core::uint32 size ); 
	static void						operator delete ( void* p );

	//////////////////////////////////////////////////////////////////////////
									Camera( ProjectType type );
									~Camera();

	void							SetPosition( XMFLOAT3 pos, XMFLOAT3 target );

	void							SetFov( float fFov );
	void							SetRatio( float fRatio );
	void							SetNearClip( float fNearClip );
	void							SetFarClip( float fFarClip );

	XMMATRIX						GetViewMatrix() const;
	XMMATRIX						GetProjMatrix() const;

	const XMFLOAT3&					GetPosition() const;

private:
	void							UpdateViewMatrix() const;
	void							UpdateProjMatrix() const;

	XMFLOAT3						m_pos;
	XMFLOAT3						m_target;
	XMFLOAT3						m_up;

	ProjectType						m_eType;

	float							m_fFov;	// radian
	float							m_fRatio;
	float							m_fNearClip;
	float							m_fFarClip;

	mutable bool					m_bDirtyViewMatrix;
	mutable bool					m_bDirtyProjMatrix;

	mutable XMMATRIX				m_viewMatrix;
	mutable XMMATRIX				m_projMatrix;
};

inline Camera::~Camera()
{

}

inline void Camera::SetPosition( XMFLOAT3 pos, XMFLOAT3 target )
{
	m_pos = pos;
	m_target = target;

	m_bDirtyViewMatrix = true;
}

inline void Camera::SetFov( float fFov )
{
	m_fFov = fFov;
	m_bDirtyProjMatrix = true;
}

inline void Camera::SetRatio( float fRatio )
{
	m_fRatio = fRatio;
	m_bDirtyProjMatrix = true;
}

inline void Camera::SetNearClip( float fNearClip )
{
	m_fNearClip = fNearClip;
	m_bDirtyProjMatrix = true;
}

inline void Camera::SetFarClip( float fFarClip )
{
	m_fFarClip = fFarClip;
	m_bDirtyProjMatrix = true;
}

inline XMMATRIX Camera::GetViewMatrix() const
{
	if ( m_bDirtyViewMatrix )
		UpdateViewMatrix();

	return m_viewMatrix;
}

inline XMMATRIX Camera::GetProjMatrix() const
{
	if ( m_bDirtyProjMatrix )
		UpdateProjMatrix();

	return m_projMatrix;
}

inline const XMFLOAT3& Camera::GetPosition() const
{
	return m_pos;
}

} // end of namespace GObject

#endif // end of #ifndef __MARS_GOBJECT_CAMERA_H__